﻿using System;
using System.Collections.Generic;
using Jayden.Dll.Web.Enums;
using Jayden.Dll.Web.Helper;
using Jayden.Dll.Web.HtmlControls;
using Jayden.Dll.Web.PayPal;

namespace Jayden.Dll.Web.Controls
{
	public class PayPalForm : Form
	{

		private Input m_Business;
		private Input m_Cmd;
		private Input m_Upload;
		private Input m_Currency;
		private Input m_Custom;
		private Input m_Invoice;
		private Input m_NotifyUrl;
		private Input m_ShoppingUrl;
		private Input m_Return;
		private Input m_CancelReturn;
		private Input m_WeightUnit;
		private Input m_WeightCart;

		private Select m_CurrencyCode;

		private int m_ItemIndex = 0;

		private A m_InvoiceLink;

		private PayPalTable m_InvoiceTable;

		public string ServerBusiness { get { return GetServerAttribute("business"); } set { SetServerAttribute("business", value); } }
		public bool ServerSandbox { get { return GetServerAttribute("sandbox") == "true"; } set { SetServerAttribute("sandbox", value ? "true" : null); } }

		public override void Load(System.Xml.XmlNode node, HtmlControlLoader loader)
		{
			Action = PayPalHelper.Url;
			Method = HtmlFormMethod.Post;

			/*
			m_Business = new Input(HtmlInputType.Hidden, "business", null);
			m_Currency = new Input(HtmlInputType.Hidden, "currency_code", "EUR");
			// should not randomize this dude ... :p
			m_Custom = new Input(HtmlInputType.Hidden, "custom", Guid.NewGuid().ToString("N"));
			m_Invoice = new Input(HtmlInputType.Hidden, "invoice", Guid.NewGuid().ToString("N"));
			// should not hardcode thoses in a common library dude ... :p
			m_NotifyUrl = new Input(HtmlInputType.Hidden, "notify_url", "http://www.vanderweyen.com/paypalIpn.html");
			m_ShoppingUrl = new Input(HtmlInputType.Hidden, "shopping_url", "http://www.vanderweyen.com/paypal.html");
			m_WeightCart = new Input(HtmlInputType.Hidden, "weight_cart", null);
			m_WeightUnit = new Input(HtmlInputType.Hidden, "weight_unit", "kgs");

			ChildControls.Add(m_Business);
			ChildControls.Add(m_Currency);
			ChildControls.Add(m_NotifyUrl);
			ChildControls.Add(m_ShoppingUrl);
			ChildControls.Add(m_Custom);
			ChildControls.Add(m_Invoice);
			*/

			m_Cmd = new Input(HtmlInputType.Hidden, "cmd", PayPalHelper.Cart);
			m_Upload = new Input(HtmlInputType.Hidden, "upload", "1");

			ChildControls.Add(m_Cmd);
			ChildControls.Add(m_Upload);

			base.Load(node, loader);

			m_InvoiceTable = GetElementByServerId<PayPalTable>("invoiceTable");
			m_InvoiceLink = GetElementByServerId<A>("invoiceLink");

			m_NotifyUrl = GetFormElement<Input>("notifyUrl", "notify_url");
			m_Return = GetFormElement<Input>("return");
			m_CancelReturn = GetFormElement<Input>("cancelReturn", "cancel_return");
			m_Invoice = GetFormElement<Input>("invoice");
			m_Business = GetFormElement<Input>("business");
			m_CurrencyCode = GetFormElement<Select>("currencyCode", "currency_code");

			m_Return.Value = "http://www.vanderweyen.com/paypal.html";
			m_CancelReturn.Value = "http://www.vanderweyen.com/paypal.html";
			m_NotifyUrl.Value = "http://www.vanderweyen.com/paypalIpn.html";


			m_CurrencyCode.AddDefaultOption();
			List<string> currencies = new List<string>(PayPalHelper.Currencies);
			currencies.Sort();
			foreach (string cur in currencies)
				m_CurrencyCode.AddOption(null, cur);

			m_Business.Value = ServerBusiness;
			if(ServerSandbox)
				Action = PayPalHelper.SandBoxUrl;
		}

		public override void ProcessHtmlRequest(HttpHandlerContext context)
		{
			List<PayPalPaymentLine> lines = new List<PayPalPaymentLine>();
			uint items = 5;
			if (context.Request["items"] != null)
				uint.TryParse(context.Request["items"], out items);

			for (int c = 0; c < items; c++)
				lines.Add(new PayPalPaymentLine() { ItemNumber = c.ToString(), Amount = 0, ItemName = "Item #" + c, Quantity = 1 });

			if(!string.IsNullOrWhiteSpace(m_Invoice.Value))
				m_InvoiceTable.AddCaption("Invoice #" + m_Invoice.Value);
			m_InvoiceTable.AddHeaders();
			AddPayPalPaymentLine(lines);

			PayPalRequest request = new PayPalRequest();
			request.Cmd = PayPalHelper.Cart;
			request.Business = ServerBusiness;
			request.UploadCart = true;
			request.CurrencyCode = "EUR";
			request.Custom = Guid.NewGuid().ToString("N");
			request.Invoice = Guid.NewGuid().ToString("N");
			request.NotifyUrl = "http://www.vanderweyen.com/paypalIpn.html";
			request.ShoppingUrl = "http://www.vanderweyen.com/paypal.html";
			request.AddPayPalPaymentLine(lines);

			m_InvoiceLink.HRef = request.GetUri(ServerSandbox).ToString(true);

			base.ProcessHtmlRequest(context);
		}

		public void AddPayPalPaymentLine(PayPalPaymentLine line)
		{
			m_ItemIndex++;
			string suffix = "_" + m_ItemIndex;
			m_InvoiceTable.ItemIndex = m_ItemIndex;
			m_InvoiceTable.ItemSuffix = suffix;
			m_InvoiceTable.AddTr(line);
		}

		public void AddPayPalPaymentLine(IEnumerable<PayPalPaymentLine> lines)
		{
			foreach (PayPalPaymentLine line in lines)
				AddPayPalPaymentLine(line);
		}
	}

	public abstract class PayPalTable : DataTable<PayPalPaymentLine>
	{
		public int ItemIndex = 0;
		public string ItemSuffix = string.Empty;
	}

	public class PayPalEditTable : PayPalTable
	{
		public override void Load(System.Xml.XmlNode node, HtmlControlLoader loader)
		{

			AddColumn(new Column("#", 50, delegate(PayPalPaymentLine value, Column column, int index) { return OneControl(new Input(HtmlInputType.Text, "item_number" + ItemSuffix, value.ItemNumber)); }, null));
			AddColumn(new Column("Name", 150, delegate(PayPalPaymentLine value, Column column, int index) { return OneControl(new Input(HtmlInputType.Text, "item_name" + ItemSuffix, value.ItemName)); }, null));
			AddColumn(new Column("Amount", 50, delegate(PayPalPaymentLine value, Column column, int index) { return OneControl(new Input(HtmlInputType.Number, "amount" + ItemSuffix, HtmlHelper.ToHtmlFloat(value.Amount)) { Step = "0.01", Min="0" }); }, null));
			AddColumn(new Column("Quantity", 50, delegate(PayPalPaymentLine value, Column column, int index) { return OneControl(new Input(HtmlInputType.Number, "quantity" + ItemSuffix, HtmlHelper.ToHtmlFloat(value.Quantity)) { Step = "1", Min = "0" }); }, null));
			AddColumn(new Column("Weight", 50, delegate(PayPalPaymentLine value, Column column, int index) { return OneControl(new Input(HtmlInputType.Number, "weight" + ItemSuffix, HtmlHelper.ToHtmlFloat(value.Weight)) { Step = "0.01", Min = "0" }); }, null));
			AddColumn(new Column("Unit", 50, delegate(PayPalPaymentLine value, Column column, int index)
			{
				Select select = new Select();
				select.Name = "weight_unit" + ItemSuffix;
				select.AddDefaultOption();
				select.AddOption(null, "kgs");
				select.AddOption(null, "lbs");
				return OneControl(select);
			}, null));

			base.Load(node, loader);
		}
	}

	public class PayPalReadOnlyTable : PayPalTable
	{

		public override void Load(System.Xml.XmlNode node, HtmlControlLoader loader)
		{

			AddColumn(new Column("#", 50, delegate(PayPalPaymentLine value, Column column, int index) { return ParseText(value.ItemNumber); }, null));
			AddColumn(new Column("Name", 150, delegate(PayPalPaymentLine value, Column column, int index) { return ParseText(value.ItemName); }, null));
			AddColumn(new Column("Amount", 50, delegate(PayPalPaymentLine value, Column column, int index) { return ParseText(value.Amount.ToString()); }, null));
			AddColumn(new Column("Quantity", 50, delegate(PayPalPaymentLine value, Column column, int index) { return ParseText(value.Quantity.ToString()); }, null));
			AddColumn(new Column("Weight", 50, delegate(PayPalPaymentLine value, Column column, int index) { return ParseText(value.Weight + " " + value.WeightUnit); }, null));

			base.Load(node, loader);
		}
	}
}
